"""
通用工具函数模块
"""

from datetime import datetime, date
from typing import Optional, List, Any
import re


def format_date(date_str: Optional[str], format_type: str = 'date') -> str:
    """
    格式化日期字符串
    
    Args:
        date_str: 日期字符串
        format_type: 格式类型 ('date' 或 'datetime')
        
    Returns:
        格式化后的日期字符串
    """
    if not date_str:
        return "无"
    
    try:
        # 尝试解析 ISO 格式日期
        dt = datetime.fromisoformat(date_str.replace('Z', '+00:00'))
        
        if format_type == 'date':
            return dt.strftime('%Y-%m-%d')
        elif format_type == 'datetime':
            return dt.strftime('%Y-%m-%d %H:%M:%S')
        else:
            return dt.strftime('%Y-%m-%d')
            
    except Exception:
        return date_str


def parse_date_input(date_input: str) -> Optional[str]:
    """
    解析用户输入的日期
    
    Args:
        date_input: 用户输入的日期字符串
        
    Returns:
        标准化的日期字符串或 None
    """
    if not date_input or not date_input.strip():
        return None
    
    date_input = date_input.strip()
    
    # 支持的日期格式
    formats = [
        '%Y-%m-%d',
        '%Y/%m/%d',
        '%m-%d',
        '%m/%d'
    ]
    
    for fmt in formats:
        try:
            if fmt in ['%m-%d', '%m/%d']:
                # 对于只有月日的格式，添加当前年份
                current_year = datetime.now().year
                parsed_date = datetime.strptime(date_input, fmt)
                parsed_date = parsed_date.replace(year=current_year)
            else:
                parsed_date = datetime.strptime(date_input, fmt)
            
            return parsed_date.date().isoformat()
            
        except ValueError:
            continue
    
    return None


def truncate_text(text: str, max_length: int = 50, suffix: str = "...") -> str:
    """
    截断文本
    
    Args:
        text: 原始文本
        max_length: 最大长度
        suffix: 截断后缀
        
    Returns:
        截断后的文本
    """
    if not text:
        return ""
    
    if len(text) <= max_length:
        return text
    
    return text[:max_length - len(suffix)] + suffix


def validate_email(email: str) -> bool:
    """
    验证邮箱格式
    
    Args:
        email: 邮箱地址
        
    Returns:
        是否为有效邮箱
    """
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return bool(re.match(pattern, email))


def safe_int(value: Any, default: int = 0) -> int:
    """
    安全转换为整数
    
    Args:
        value: 要转换的值
        default: 默认值
        
    Returns:
        转换后的整数
    """
    try:
        return int(value)
    except (ValueError, TypeError):
        return default


def safe_float(value: Any, default: float = 0.0) -> float:
    """
    安全转换为浮点数
    
    Args:
        value: 要转换的值
        default: 默认值
        
    Returns:
        转换后的浮点数
    """
    try:
        return float(value)
    except (ValueError, TypeError):
        return default


def pluralize(count: int, singular: str, plural: str = None) -> str:
    """
    根据数量返回单复数形式
    
    Args:
        count: 数量
        singular: 单数形式
        plural: 复数形式
        
    Returns:
        适当的单复数形式
    """
    if plural is None:
        plural = singular + "s"
    
    return singular if count == 1 else plural


def format_duration(seconds: int) -> str:
    """
    格式化时间间隔
    
    Args:
        seconds: 秒数
        
    Returns:
        格式化的时间字符串
    """
    if seconds < 60:
        return f"{seconds}秒"
    elif seconds < 3600:
        minutes = seconds // 60
        return f"{minutes}分钟"
    elif seconds < 86400:
        hours = seconds // 3600
        return f"{hours}小时"
    else:
        days = seconds // 86400
        return f"{days}天"


def get_relative_time(target_date: datetime) -> str:
    """
    获取相对时间描述
    
    Args:
        target_date: 目标日期
        
    Returns:
        相对时间描述
    """
    now = datetime.now()
    delta = target_date - now
    
    if delta.days > 0:
        return f"{delta.days}天后"
    elif delta.days < 0:
        return f"{abs(delta.days)}天前"
    else:
        hours = delta.seconds // 3600
        if hours > 0:
            return f"{hours}小时后"
        else:
            minutes = delta.seconds // 60
            if minutes > 0:
                return f"{minutes}分钟后"
            else:
                return "现在"


def clean_filename(filename: str) -> str:
    """
    清理文件名，移除非法字符
    
    Args:
        filename: 原始文件名
        
    Returns:
        清理后的文件名
    """
    # 移除或替换非法字符
    illegal_chars = r'[<>:"/\\|?*]'
    cleaned = re.sub(illegal_chars, '_', filename)
    
    # 移除首尾空格和点
    cleaned = cleaned.strip(' .')
    
    # 确保文件名不为空
    if not cleaned:
        cleaned = "untitled"
    
    return cleaned


def format_file_size(size_bytes: int) -> str:
    """
    格式化文件大小
    
    Args:
        size_bytes: 字节数
        
    Returns:
        格式化的文件大小字符串
    """
    if size_bytes == 0:
        return "0 B"
    
    size_names = ["B", "KB", "MB", "GB", "TB"]
    i = 0
    
    while size_bytes >= 1024 and i < len(size_names) - 1:
        size_bytes /= 1024.0
        i += 1
    
    return f"{size_bytes:.1f} {size_names[i]}"


def chunk_list(lst: List[Any], chunk_size: int) -> List[List[Any]]:
    """
    将列表分块
    
    Args:
        lst: 原始列表
        chunk_size: 块大小
        
    Returns:
        分块后的列表
    """
    return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)]


def is_today(date_str: Optional[str]) -> bool:
    """
    检查日期是否为今天
    
    Args:
        date_str: 日期字符串
        
    Returns:
        是否为今天
    """
    if not date_str:
        return False
    
    try:
        target_date = datetime.fromisoformat(date_str.replace('Z', '+00:00')).date()
        return target_date == date.today()
    except Exception:
        return False


def is_overdue(date_str: Optional[str]) -> bool:
    """
    检查日期是否已过期
    
    Args:
        date_str: 日期字符串
        
    Returns:
        是否已过期
    """
    if not date_str:
        return False
    
    try:
        target_date = datetime.fromisoformat(date_str.replace('Z', '+00:00'))
        return target_date < datetime.now()
    except Exception:
        return False